#ifdef KITSCHY_DEBUG_MEMORY 
#include "debug_memorymanager.h"
#endif

#ifdef WIN32
#include "windows.h"
#else
#include <sys/time.h>
#include <time.h>
#endif
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "stdarg.h"
#include "math.h"

#include "BList.h"

#include "symbol.h"
#include "sort.h"
#include "ontology.h"
#include "featureterm.h"
#include "FTKBase.h"
#include "AUfeatureterm.h"
#include "FT_refinement.h"
#include "FT_generalization.h"

#include "psm.h"

// #include "AWEntity.h"

Hypothesis::Hypothesis(void)
{
	m_default_solution=0;
} /* Hypothesis::Hypothesis */ 


Hypothesis::Hypothesis(Hypothesis *h)
{
	m_patterns.Copy(h->m_patterns);
	m_solutions.Copy(h->m_solutions);
	m_reliability.Copy(h->m_reliability);
	m_default_solution=new FeatureTerm(h->m_default_solution);
} /* Hypothesis::Hypothesis */ 


Hypothesis::~Hypothesis()
{
	m_patterns.Delete();
	m_solutions.Delete();
	delete m_default_solution;
	m_default_solution=0;
} /* Hypothesis::~Hypothesis */ 


FeatureTerm *Hypothesis::solve_problem(FeatureTerm *problem,FTKBase *domain_model)
{
	List<FeatureTerm> l1,l2;
	List<float> l3;
	FeatureTerm *patt,*sol;
	float *reliability;
	float candidate_reliability=0;
	FeatureTerm *candidate_sol=0;
	char *s;

	l1.Instance(m_patterns);
	l2.Instance(m_solutions);
	l3.Instance(m_reliability);
	while(l1.Iterate(patt) && l2.Iterate(sol) && l3.Iterate(reliability)) {
		if (patt->subsumes(problem) &&
			(candidate_sol==0 || *reliability>candidate_reliability)) {
			delete candidate_sol;
			candidate_sol=new FeatureTerm(sol);
			candidate_reliability=*reliability;
		} /* if */ 
	} /* while */ 

	if (candidate_sol!=0) {
		s=candidate_sol->toStringNOOS(domain_model);
		printf("Hypothesis: %s with reliability %f\n",s,candidate_reliability);
		delete s;
		return candidate_sol;
	} /* if */ 

	if (m_default_solution!=0) {
		printf("Hypothesis: not covered by any pattern. Using default solution...\n");
		s=m_default_solution->toStringNOOS(domain_model);
		printf("Hypothesis: %s\n",s);
		delete s;
		return new FeatureTerm(m_default_solution);
	} else {
		printf("Hypothesis: not covered by any pattern and no default solution...\n");
		return 0;
	} /* if */ 
} /* Hypothesis::solve_problem */ 


Prediction *Hypothesis::generate_prediction(FeatureTerm *problem,FTKBase *domain_model)
{
	Prediction *p;
	List<FeatureTerm> l1,l2;
	List<float> l3;
	FeatureTerm *patt,*sol;
	float *reliability;
	float candidate_reliability=0;
	FeatureTerm *candidate_sol=0;
	FeatureTerm *candidate_patt=0;
	char *s;

	l1.Instance(m_patterns);
	l2.Instance(m_solutions);
	l3.Instance(m_reliability);
	while(l1.Iterate(patt) && l2.Iterate(sol) && l3.Iterate(reliability)) {
		if (patt->subsumes(problem) &&
			(candidate_sol==0 || *reliability>candidate_reliability)) {
			delete candidate_sol;
			candidate_sol=new FeatureTerm(sol);
			candidate_reliability=*reliability;
			candidate_patt=patt;
		} /* if */ 
	} /* while */ 

	if (candidate_sol!=0) {
		s=candidate_sol->toStringNOOS(domain_model);
		printf("Hypothesis: %s with reliability %f\n",s,candidate_reliability);
		delete s;

		p = new Prediction(new FeatureTerm(problem));
		p->solutions.Add(candidate_sol);
		p->justifications.Add(new FeatureTerm(candidate_patt));
		p->support.Add(new int(0));
		return p;
	} /* if */ 

	if (m_default_solution!=0) {
		printf("Hypothesis: not covered by any pattern. Using default solution...\n");
		s=m_default_solution->toStringNOOS(domain_model);
		printf("Hypothesis: %s\n",s);
		delete s;
		p = new Prediction(new FeatureTerm(problem));
		p->solutions.Add(m_default_solution);
		p->justifications.Add(new FeatureTerm());
		p->support.Add(new int(0));
		return p;
	} else {
		printf("Hypothesis: not covered by any pattern and no default solution...\n");
		return 0;
	} /* if */ 
} /* Hypothesis::generate_prediction */ 


void Hypothesis::show_rule_set(FTKBase *domain_model)
{
	List<FeatureTerm> l,l2;
	FeatureTerm *p,*sol;
	char *s;

	printf("\nHypothesis: rules learned (%i): ----------------------\n",m_patterns.Length());
	if (m_default_solution!=0) {
		s = m_default_solution->toStringNOOS(domain_model);
		printf("Default Solution: %s\n",s);
		delete []s;
	} // if 

	l.Instance(m_patterns);
	l2.Instance(m_solutions);
	l.Rewind();
	l2.Rewind();
	while(l.Iterate(p) && l2.Iterate(sol)) {
		s=sol->toStringNOOS(domain_model);
		printf("- Rule for %s:\n",s);
		delete []s;
		s=p->toStringNOOS(domain_model);
		printf("%s\n\n",s);
		delete []s;
	} /* while */ 

	printf("\n");
} /* Hypothesis::show_rule_set */ 


#ifdef __AW_ENTITY

void Hypothesis::report_rule_set(FTKBase *domain_model)
{
	List<FeatureTerm> l,l2;
	FeatureTerm *p,*sol;
	char *s;

	AW_Entity::write_debug_report("\nHypothesis: rules learned (%i): ----------------------\n",m_patterns.Length());
	if (m_default_solution!=0) {
		s = m_default_solution->toStringNOOS(domain_model);
		AW_Entity::write_debug_report("Default Solution: %s\n",s);
		delete []s;
	} // if 

	l.Instance(m_patterns);
	l2.Instance(m_solutions);
	l.Rewind();
	l2.Rewind();
	while(l.Iterate(p) && l2.Iterate(sol)) {
		s=sol->toStringNOOS(domain_model);
		AW_Entity::write_debug_report("- Rule for %s:\n",s);
		delete []s;
		s=p->toStringNOOS(domain_model);
		AW_Entity::write_debug_report("%s\n\n",s);
		delete []s;
	} /* while */ 

	AW_Entity::write_debug_report("\n");
} /* Hypothesis::show_rule_set */ 


#endif